﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Collections;
using LiteFramework;
using System.Text;

namespace Website.Action
{
    #region Base Class

    /// <summary>
    /// 以“{”、“}”包裹的Json对象
    /// <para>添加进来的项全部不指定“key”值，将生成以“[”、“]”包裹的Json包集合</para>
    /// </summary>
    public class Json : IJson
    {
        bool hasKey = false; // 判断Json是否存在键名，存在时，将处理为一个Json对象；否则Json对象集合
        StringBuilder sb = new StringBuilder();

        public Json Add<T>(string key, T value, string formatString = null)
        {
            this._addKey(key);
            sb.Append(JsonHelper.FormatJsonValue(value, formatString));
            return this;
        }

        public Json Add(string key, IJson value)
        {
            this._addKey(key);
            sb.Append(value != null ? value.ToJsonString() : "\"\"");
            return this;
        } // IJson

        #region private
        private void _addKey(string key)
        {
            if (sb.Length > 0) sb.Append(",");
            if (!string.IsNullOrEmpty(key))
            {
                hasKey = true;
                sb.Append("\"" + key + "\":"); // 允许Key为空
            }
        }

        #endregion

        public string ToJsonString()
        {
            if (hasKey)
                return "{" + sb.ToString() + "}";
            else
                return "[" + sb.ToString() + "]";
        }

        public override string ToString()
        {
            return this.ToJsonString();
        }
    }

    /// <summary>
    /// 以“[”、“]”包裹的Json对象包
    /// </summary>
    public class JsonPacket : IJson
    {
        List<IJson> list = new List<IJson>();

        /// <summary>
        /// 添加项
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public JsonPacket Add(IJson value)
        {
            if (value != null) list.Add(value);
            return this;
        }

        public string ToJsonString()
        {
            return "[" + string.Join(",", list.Select(i => i.ToJsonString())) + "]";
        }
    }

    /// <summary>
    /// 以“[”、“]”包裹的Json对象包
    /// </summary>
    public class JsonSinglePack<T> : IJson
    {
        List<T> list = new List<T>();

        /// <summary>
        /// 添加项
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public JsonSinglePack<T> Add(T value)
        {
            if (value != null) list.Add(value);
            return this;
        }

        /// <summary>
        /// 添加项
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        public JsonSinglePack<T> AddRange(IEnumerable<T> collection)
        {
            if (collection != null) list.AddRange(collection);
            return this;
        }

        public string ToJsonString()
        {
            return "[" + string.Join(",", list.Select(i => JsonHelper.FormatJsonValue(i))) + "]";
        }
    }

    #region Json响应包基类: AbsResponseJSon / ResponseJSonPacket<T>。

    /// <summary>
    /// Json对象顶层基类。
    /// <para>　　ToString() 方法返回一个Json对象字符串。</para>
    /// <para>　　</para>
    /// <para>　　status: 状态码，数字</para>
    /// <para>　　message:状态说明</para>
    /// <para>　　ok:操作成功。是否期望的结果</para>
    /// </summary>
    [Serializable]
    public abstract class AbsResponseJSon
    {
        public AbsResponseJSon()
        {
            this.status = 200;
            this.message = "ok";
        }

        /* statu说明:
         * 
                HTTP: Status 1xx  (临时响应)            -> 表示临时响应并需要请求者继续执行操作的状态代码。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP: Status 100 (继续)                 -> 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分，正在等待其余部分。
                HTTP: Status 101 (切换协议)             -> 请求者已要求服务器切换协议，服务器已确认并准备切换。
                
                
                HTTP Status 2xx  (成功)                 ->表示成功处理了请求的状态代码;
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP Status 200 (成功)                  -> 服务器已成功处理了请求。 通常，这表示服务器提供了请求的网页。
                HTTP Status 201 (已创建)                -> 请求成功并且服务器创建了新的资源。
                HTTP Status 202 (已接受)                -> 服务器已接受请求，但尚未处理。
                HTTP Status 203 (非授权信息)            -> 服务器已成功处理了请求，但返回的信息可能来自另一来源。
                HTTP Status 204 (无内容)                -> 服务器成功处理了请求，但没有返回任何内容。
                HTTP Status 205 (重置内容)              -> 服务器成功处理了请求，但没有返回任何内容。
                HTTP Status 206 (部分内容)              -> 服务器成功处理了部分 GET 请求。

                
                HTTP: Status 3xx （重定向）             -> 表示要完成请求，需要进一步操作。 通常，这些状态代码用来重定向。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP Status 300 （多种选择）            -> 针对请求，服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作，或提供操作列表供请求者选择。 
                HTTP Status 301 （永久移动）            -> 请求的网页已永久移动到新位置。 服务器返回此响应（对 GET 或 HEAD 请求的响应）时，会自动将请求者转到新位置。
                HTTP Status 302 （临时移动）            -> 服务器目前从不同位置的网页响应请求，但请求者应继续使用原有位置来进行以后的请求。
                HTTP Status 303 （查看其他位置）        -> 请求者应当对不同的位置使用单独的 GET 请求来检索响应时，服务器返回此代码。
                HTTP Status 304 （未修改）              -> 自从上次请求后，请求的网页未修改过。 服务器返回此响应时，不会返回网页内容。 
                HTTP Status 305 （使用代理）            -> 请求者只能使用代理访问请求的网页。 如果服务器返回此响应，还表示请求者应使用代理。 
                HTTP Status 307 （临时重定向）          -> 服务器目前从不同位置的网页响应请求，但请求者应继续使用原有位置来进行以后的请求。 

                
                HTTP Status 4xx (请求错误)              -> 这些状态代码表示请求可能出错，妨碍了服务器的处理。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP Status 400 （错误请求）            -> 服务器不理解请求的语法。
                HTTP Status 401 （未授权）              -> 请求要求身份验证。 对于需要登录的网页，服务器可能返回此响应。
                HTTP Status 403 （禁止）                -> 服务器拒绝请求。
                HTTP Status 404 （未找到）              -> 服务器找不到请求的网页。
                HTTP Status 405 （方法禁用）            -> 禁用请求中指定的方法。
                HTTP Status 406 （不接受）              -> 无法使用请求的内容特性响应请求的网页。
                HTTP Status 407 （需要代理授权）        -> 此状态代码与 401（未授权）类似，但指定请求者应当授权使用代理。
                HTTP Status 408 （请求超时）            -> 服务器等候请求时发生超时。
                HTTP Status 409 （冲突）                -> 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
                HTTP Status 410 （已删除）              -> 如果请求的资源已永久删除，服务器就会返回此响应。
                HTTP Status 411 （需要有效长度）        -> 服务器不接受不含有效内容长度标头字段的请求。
                HTTP Status 412 （未满足前提条件）      -> 服务器未满足请求者在请求中设置的其中一个前提条件。
                HTTP Status 413 （请求实体过大）        -> 服务器无法处理请求，因为请求实体过大，超出服务器的处理能力。
                HTTP Status 414 （请求的 URI 过长）     -> 请求的 URI（通常为网址）过长，服务器无法处理。
                HTTP Status 415 （不支持的媒体类型）    -> 请求的格式不受请求页面的支持。
                HTTP Status 416 （请求范围不符合要求）  -> 如果页面无法提供请求的范围，则服务器会返回此状态代码。
                HTTP Status 417 （未满足期望值）        -> 服务器未满足”期望”请求标头字段的要求。


                HTTP Status 5xx （服务器错误）          -> 这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误，而不是请求出错。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                代码详细及说明:
                HTTP Status 500 （服务器内部错误）      -> 服务器遇到错误，无法完成请求。
                HTTP Status 501 （尚未实施）            -> 服务器不具备完成请求的功能。 例如，服务器无法识别请求方法时可能会返回此代码。
                HTTP Status 502 （错误网关）            -> 服务器作为网关或代理，从上游服务器收到无效响应。
                HTTP Status 503 （服务不可用）          -> 服务器目前无法使用（由于超载或停机维护）。 通常，这只是暂时状态。
                HTTP Status 504 （网关超时）            -> 服务器作为网关或代理，但是没有及时从上游服务器收到请求。
                HTTP Status 505 （HTTP 版本不受支持）   -> 服务器不支持请求中所用的 HTTP 协议版本。
                    
                    
                HTTP Status 9xx （自定义错误）          -> 这些错误是业务逻辑错误。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                代码详细及说明:
                HTTP Status 900 （非法请求）            -> 无法明确请求的资源。
                HTTP Status 901 （登陆超时）            -> 当前登陆已经超时，要求重新登陆。
            */

        /// <summary>
        /// 状态:
        /// <para>　　200: ok</para>
        /// <para>　　400: 错误请求。服务器不理解请求的语法。</para>
        /// <para>　　401: 未授权</para>
        /// <para>　　404: 未找到</para>
        /// <para>　　412: 未满足前提条件</para>
        /// <para>　　500: 服务器内部错误</para>
        /// <para>　　900: 非法的请求，未指定action</para>
        /// </summary>
        public int status { get; set; }
        /// <summary>
        /// 信息
        /// </summary>
        public string message { get; set; }
        /// <summary>
        /// 一般用于判断操作是否成功。不建议直接赋值，赋值请考虑status属性
        /// </summary>
        public virtual bool ok
        {
            get { return this.status == 200; }
            set { this.status = (value ? 200 : 406); /* 406 （不接受） */ }
        }

        #region 扩展属性

        /// <summary>
        /// 扩展属性
        /// </summary>
        public Dictionary<string, object> extend { get; set; }
        /// <summary>
        /// 增加扩展属性。UI访问 {json}.extend.key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="obj"></param>
        public void addExtend(string key, object obj)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException("key");

            if (extend == null)
                extend = new Dictionary<string, object>();

            if (obj == null)
                obj = "";

            if (!extend.Keys.Contains(key))
                extend[key] = obj;
            else
                extend.Add(key, obj);
        }

        #endregion

        public void setError<E>(E ex)
            where E : Exception
        {
            this.status = 400; // 错误请求
            this.message = ex.Message;
        }

        public override string ToString()
        {
            return JsonHelper.ToSafeJson(this);
        }
    }

    /// <summary>
    /// Json包。在data属性中存储包的数据）
    /// </summary>
    /// <typeparam name="T">结果集data的类型。如 Customer / Customer[]，作为数组时，代表包中有多个数据</typeparam>
    public class ResponseJSonPacket<T> : AbsResponseJSon
    {
        /// <summary>
        /// 数据包
        /// </summary>
        public T data { get; set; }
        /// <summary>
        /// 判定数据包是否有返回值。set访问器无效
        /// </summary>
        public bool hasData
        {
            get
            {
                if (this.ok && this.data != null)
                    return (this.data is IList) ? (this.data as IList).Count > 0 : true; // 数组时，元素数需大于0

                return false;
            }
            set { throw new NotSupportedException("set访问器无效。"); }
        }
    }

    #endregion

    #region 定义类型转换的方法: IConvert<T, F>。

    /// <summary>
    /// 定义类型转换的方法。指示一个类可以从其他类转换得到
    /// </summary>
    /// <typeparam name="T">To，目标类型</typeparam>
    /// <typeparam name="F">From，数据源类型</typeparam>
    public interface IConvert<T, F>
        where T : class
        where F : class
    {
        T ConvertFrom(F source);
    }

    #endregion

    #region 可转换为Json的类: ConvertibleBag<T, F>。

    /// <summary>
    /// 可转换类。指示类T可以通过类型F转换
    /// </summary>
    /// <typeparam name="T">目标类型</typeparam>
    /// <typeparam name="F">数据源类型</typeparam>
    [Serializable]
    public abstract class ConvertibleBag<T, F> : IConvert<T, F>
        where T : ConvertibleBag<T, F>, new()
        where F : class
    {
        public ConvertibleBag()
        {
            //this.status = 200;
            //this.message = "ok";
            //this.data = "";
        }

        public ConvertibleBag(F source)
            : this()
        {
            this.ConvertFrom(source);
        }

        /* statu说明:
         * 
                HTTP: Status 1xx （临时响应）           -> 表示临时响应并需要请求者继续执行操作的状态代码。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP: Status 100 （继续）               -> 请求者应当继续提出请求。 服务器返回此代码表示已收到请求的第一部分，正在等待其余部分。
                HTTP: Status 101 （切换协议）           -> 请求者已要求服务器切换协议，服务器已确认并准备切换。
                
                
                HTTP Status 2xx （成功）                ->表示成功处理了请求的状态代码;
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP Status 200 （成功）                -> 服务器已成功处理了请求。 通常，这表示服务器提供了请求的网页。
                HTTP Status 201 （已创建）              -> 请求成功并且服务器创建了新的资源。
                HTTP Status 202 （已接受）              -> 服务器已接受请求，但尚未处理。
                HTTP Status 203 （非授权信息）          -> 服务器已成功处理了请求，但返回的信息可能来自另一来源。
                HTTP Status 204 （无内容）              -> 服务器成功处理了请求，但没有返回任何内容。
                HTTP Status 205 （重置内容）            -> 服务器成功处理了请求，但没有返回任何内容。
                HTTP Status 206 （部分内容）            -> 服务器成功处理了部分 GET 请求。

                
                HTTP: Status 3xx （重定向）             -> 表示要完成请求，需要进一步操作。 通常，这些状态代码用来重定向。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP Status 300 （多种选择）            -> 针对请求，服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作，或提供操作列表供请求者选择。 
                HTTP Status 301 （永久移动）            -> 请求的网页已永久移动到新位置。 服务器返回此响应（对 GET 或 HEAD 请求的响应）时，会自动将请求者转到新位置。
                HTTP Status 302 （临时移动）            -> 服务器目前从不同位置的网页响应请求，但请求者应继续使用原有位置来进行以后的请求。
                HTTP Status 303 （查看其他位置）        -> 请求者应当对不同的位置使用单独的 GET 请求来检索响应时，服务器返回此代码。
                HTTP Status 304 （未修改）              -> 自从上次请求后，请求的网页未修改过。 服务器返回此响应时，不会返回网页内容。 
                HTTP Status 305 （使用代理）            -> 请求者只能使用代理访问请求的网页。 如果服务器返回此响应，还表示请求者应使用代理。 
                HTTP Status 307 （临时重定向）          -> 服务器目前从不同位置的网页响应请求，但请求者应继续使用原有位置来进行以后的请求。 

                
                HTTP Status 4xx （请求错误）            -> 这些状态代码表示请求可能出错，妨碍了服务器的处理。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                详细代码说明:
                HTTP Status 400 （错误请求）            -> 服务器不理解请求的语法。
                HTTP Status 401 （未授权）              -> 请求要求身份验证。 对于需要登录的网页，服务器可能返回此响应。
                HTTP Status 403 （禁止）                -> 服务器拒绝请求。
                HTTP Status 404 （未找到）              -> 服务器找不到请求的网页。
                HTTP Status 405 （方法禁用）            -> 禁用请求中指定的方法。
                HTTP Status 406 （不接受）              -> 无法使用请求的内容特性响应请求的网页。
                HTTP Status 407 （需要代理授权）        -> 此状态代码与 401（未授权）类似，但指定请求者应当授权使用代理。
                HTTP Status 408 （请求超时）            -> 服务器等候请求时发生超时。
                HTTP Status 409 （冲突）                -> 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
                HTTP Status 410 （已删除）              -> 如果请求的资源已永久删除，服务器就会返回此响应。
                HTTP Status 411 （需要有效长度）        -> 服务器不接受不含有效内容长度标头字段的请求。
                HTTP Status 412 （未满足前提条件）      -> 服务器未满足请求者在请求中设置的其中一个前提条件。
                HTTP Status 413 （请求实体过大）        -> 服务器无法处理请求，因为请求实体过大，超出服务器的处理能力。
                HTTP Status 414 （请求的 URI 过长）     -> 请求的 URI（通常为网址）过长，服务器无法处理。
                HTTP Status 415 （不支持的媒体类型）    -> 请求的格式不受请求页面的支持。
                HTTP Status 416 （请求范围不符合要求）  -> 如果页面无法提供请求的范围，则服务器会返回此状态代码。
                HTTP Status 417 （未满足期望值）        -> 服务器未满足”期望”请求标头字段的要求。


                HTTP Status 5xx （服务器错误）          -> 这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误，而不是请求出错。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                代码详细及说明:
                HTTP Status 500 （服务器内部错误）      -> 服务器遇到错误，无法完成请求。
                HTTP Status 501 （尚未实施）            -> 服务器不具备完成请求的功能。 例如，服务器无法识别请求方法时可能会返回此代码。
                HTTP Status 502 （错误网关）            -> 服务器作为网关或代理，从上游服务器收到无效响应。
                HTTP Status 503 （服务不可用）          -> 服务器目前无法使用（由于超载或停机维护）。 通常，这只是暂时状态。
                HTTP Status 504 （网关超时）            -> 服务器作为网关或代理，但是没有及时从上游服务器收到请求。
                HTTP Status 505 （HTTP 版本不受支持）   -> 服务器不支持请求中所用的 HTTP 协议版本。
                    
                    
                HTTP Status 9xx （自定义错误）          -> 这些错误是业务逻辑错误。
                ---------------------------------------------------------------------------------------------------------------------------------------------------------
                代码详细及说明:
                HTTP Status 900 （非法请求）            -> 无法明确请求的资源。
                HTTP Status 901 （登陆超时）            -> 当前登陆已经超时，要求重新登陆。
            */

        ///// <summary>
        ///// 状态:
        ///// <para>　　200: ok</para>
        ///// <para>　　404: not found</para>
        ///// <para>　　901: timeout</para>
        ///// <para>　　xxx: error</para>
        ///// </summary>
        //public int status { get; set; }
        ///// <summary>
        ///// 信息
        ///// </summary>
        //public string message { get; set; }
        ///// <summary>
        ///// 数据包
        ///// </summary>
        //public object data { get; set; }

        public abstract T ConvertFrom(F source);

        public virtual T[] ExchangeFrom(F[] sources)
        {
            if (sources != null && sources.Length > 0)
            {
                List<T> list = new List<T>();
                foreach (F item in sources)
                {
                    T result = ConvertFrom(item);
                    if (result != null)
                        list.Add(result);
                }

                return list.ToArray();
            }
            return null;
        }

        /// <summary>
        /// 将传入的参数转换为等效的实例
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static T Parse(F s)
        {
            return ConvertFactory<T, F>.Exchange(s);
        }
        /// <summary>
        /// 将传入的参数转换为等效的实例
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static T[] Parse(F[] s)
        {
            return ConvertFactory<T, F>.Exchange(s);
        }

        public override string ToString()
        {
            return JsonHelper.ToSafeJson(this);
        }
    }

    #endregion

    #region 类型转换工厂: ConvertFactory<T, S>。

    public class ConvertFactory<T, S>
        where T : class, IConvert<T, S>, new()
        where S : class
    {
        public static T Exchange(S source)
        {
            if (source == null)
                return null;

            T t = new T();
            t.ConvertFrom(source);

            return t;
        }

        public static T[] Exchange(S[] sources)
        {
            if (sources == null || sources.Length == 0)
                return null;

            List<T> list = new List<T>();
            foreach (S s in sources)
            {
                T t = Exchange(s);
                if (t != null)
                    list.Add(t);
            }

            return list.ToArray();
        }
    }

    #endregion

    #region Json工具类
    public class JsonHelper
    {
        /// <summary>
        /// 格式化Json键值，数字/枚举/布尔值不加引号，其他都加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="formatString">如，N2 / yyyy-MM / HH:mm</param>
        /// <returns></returns>
        public static string FormatJsonValue<T>(T value, string formatString = null)
        {
            if (value == null) return (typeof(T).IsArray) ? "[]" : "\"\"";
            //if (value is IDictionary) return FormatJsonValues((IDictionary)value, formatString);
            if (!(value is String) && value is IEnumerable) return FormatJsonValues((IEnumerable)value, formatString); // IEnumerable

            Type targetType = value.GetType();
            //if (targetType.IsAssignableFrom(typeof(KeyValuePair<,>)))
            if (targetType.IsValueType && targetType.Name == "KeyValuePair`2")
            {
                var tmp_key = targetType.GetProperty("Key").GetValue(value);
                var tmp_value = targetType.GetProperty("Value").GetValue(value);

                return "{\"" + tmp_key + "\":" + FormatJsonValue(tmp_value, formatString) + "}";
            }

            if (string.IsNullOrEmpty(formatString))
            {
                if (value is Single || value is Double)
                    formatString = "{0:N2}";
                else if (value is DateTime)
                    formatString = "{0:yyyy-MM-dd HH:mm:ss}";
                else
                    formatString = "{0}";
            }
            else if (!formatString.Contains('{'))
            {
                formatString = "{0:" + formatString + "}";
            }

            if (targetType.IsEnum) // Enum
                return Convert.ToInt64(value).ToString();
            else if (value is IJson) // IJson
                return ((IJson)value).ToJsonString();
            else if (targetType == typeof(Boolean)) // DateTime
                return value.ToString().ToLower();
            else if (value is IntPtr
                    || value is Int16
                    || value is Int32
                    || value is Int64
                    || value is UIntPtr
                    || value is UInt16
                    || value is UInt32
                    || value is UInt64
                    || value is Single
                    || value is Double
                    || value is Decimal)
                return string.Format(formatString, value);
            else
                return string.Format("\"" + formatString + "\"", value);
        }

        public static string FormatJsonValues(IEnumerable values, string formatString = null)
        {
            string str = null;
            foreach (var value in values)
            {
                if (!string.IsNullOrEmpty(str)) str += ",";
                str += FormatJsonValue(value, formatString);
            }

            return "[" + str + "]";
        }
        //public static string FormatJsonValues<K, V>(IDictionary<K, V> dict, string formatString = null)
        //{
        //    string str = null;
        //    foreach (var item in dict)
        //    {
        //        if (!string.IsNullOrEmpty(str)) str += ",";
        //        str += "\"" + item.Key + "\":";
        //        str += FormatJsonValue(item.Value, formatString);
        //    }

        //    return "[" + str + "]";
        //}

        /// <summary>
        /// 获取安全的Json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToSafeJson(object obj)
        {
            if (obj == null)
                return string.Empty;
            else
            {
                //return Newtonsoft.Json.JsonConvert.SerializeObject(obj).Replace(":null,", ":\"\","); // 此方法会忽略ScriptIgnore标签的对象属性
                JavaScriptSerializer formater = new JavaScriptSerializer();
                return formater.Serialize(obj).Replace(":null,", ":\"\",")
                                              .Replace(":null}", ":\"\"}")
                                              .Replace(":null]", ":\"\"]")
                                              .Replace(":null)", ":\"\")");
            }
        }

        public static string TestJson()
        {
            Dictionary<string, int> dict = new Dictionary<string, int>();
            dict.Add("Dict1", 21);
            dict.Add("Dict2", 22);
            dict.Add("Dict3", 23);
            dict.Add("Dict4", 24);

            List<KeyValuePair<string, int>> keyValues = new List<KeyValuePair<string, int>>();
            keyValues.Add(new KeyValuePair<string, int>("KeyValues1", 31));
            keyValues.Add(new KeyValuePair<string, int>("KeyValues2", 32));
            keyValues.Add(new KeyValuePair<string, int>("KeyValues3", 33));
            keyValues.Add(new KeyValuePair<string, int>("KeyValues4", 34));

            List<string> stringList = new List<string>();
            stringList.Add("stringList1");
            stringList.Add("stringList2");
            stringList.Add("stringList3");
            stringList.Add("stringList4");

            Json json = new Json();
            json.Add("int[]", new int[] { 1, 2, 3, 4 });
            json.Add("string[]", new string[] { "S1", "S2", "S3", "S4" });
            json.Add("object[]", new object[] { 11, 12, 13, 14 });
            json.Add("dict", dict);
            json.Add("keyValues", keyValues);
            json.Add("stringList", stringList);
            json.Add("int", 1);
            json.Add("float", 1.2);
            json.Add("datetime", DateTime.Now);
            json.Add("enum", LiteFramework.Enum.Gender.Male);
            json.Add("string", "string");

            return json.ToJsonString();
        }
    }
    #endregion

    #endregion

    #region Json_Role
    [Serializable]
    public class Json_Role : ConvertibleBag<Json_Role, LiteFramework.Model.Role>
    {
        #region Properties
        public string RoleId { get; set; }
        public string RoleName { get; set; }
        public string Description { get; set; }
        public DateTime TimeCreated { get; set; }
        #endregion

        public override Json_Role ConvertFrom(LiteFramework.Model.Role source)
        {
            if (source == null) return null;

            this.RoleId = source.Id;
            this.RoleName = source.Name;
            this.Description = source.Description;
            this.TimeCreated = source.TimeCreated;

            return this;
        }
    }
    #endregion

    #region Json_User
    [Serializable]
    public class Json_User : ConvertibleBag<Json_User, LiteFramework.Model.User>
    {
        #region Properties

        public int ID { get; set; }
        public bool Active { get; set; }
        public string UserName { get; set; }
        public string RealName { get; set; }
        public string NickName { get; set; }
        /// <summary>
        /// 性别
        /// </summary>
        public string Gender { get; set; }
        /// <summary>
        /// 性别。0 男, 1 女
        /// </summary>
        public int GenderCode { get; set; }


        public string CompanyName { get; set; }

        public string OrganizationName { get; set; }

        public string DepartmentName { get; set; }


        public string Mobile { get; set; }
        public string Tel { get; set; }
        public string Email { get; set; }
        public string Remark { get; set; }

        #endregion

        public override Json_User ConvertFrom(LiteFramework.Model.User source)
        {
            if (source == null) return null;

            this.ID = source.ID;
            this.Active = Active;
            this.UserName = source.UserName;
            this.RealName = source.RealName;
            this.NickName = source.NickName;
            this.Gender = source.Gender == LiteFramework.Enum.Gender.Female ? "女" : "男";
            this.GenderCode = (int)source.Gender;

            this.CompanyName = source.CompanyName;
            this.OrganizationName = source.OrganizationName;
            this.DepartmentName = source.DepartmentName;

            this.Mobile = source.Mobile;
            this.Tel = source.Mobile;
            this.Email = source.Email;
            this.Remark = source.Remark;

            return this;
        }
    }
    #endregion
}